package bch.netty.handler;

import io.netty.buffer.*;

import io.netty.util.*;
import io.netty.util.internal.PlatformDependent;

/**
 * {@link AttributeMap}
 * {@link HashedWheelTimer}
 * {@link io.netty.util.ConstantPool}
 * {@link io.netty.util.concurrent.FastThreadLocal}
 * {@link io.netty.util.Recycler}
 * <p>
 * {@link io.netty.buffer.ByteBuf}
 * {@link AbstractReferenceCountedByteBuf} : 引用计数
 * Pooled UnPooled
 * Pooled:
 * 性能高，减少 GC
 * 实现复杂，可能有内存泄露风险（需要手动 release()）
 * UnPooled:
 * 简单，不用担心池内碎片
 * 频繁分配回收，GC 压力大
 * Unsafe Safe
 * Unsafe:
 * 直接操作内存，不受 GC 管理，适合高性能场景
 * 直接操作堆外内存，不受 JVM 内存管理，适合高性能场景
 * 适合需要高性能的场景，如网络 I/O、加密解密、数据库操作等
 * 非Unsafe:
 * 通过标准的 ByteBuffer API 操作
 * Heap Direct
 * heap:
 * byte[]
 * 分配速度快，GC 可管理，适合需要频繁访问的场景
 * 网络 I/O 时需要多一次拷贝（先从堆复制到内核的 DirectBuffer 再写 socket）
 * direct:
 * ByteBuffer.allocateDirect()
 * 写 socket/读 socket 时，数据可以直接写入内核缓冲区，避免一次用户态 → 内核态拷贝
 * 不受 GC 管理，回收依赖引用计数
 * <p>
 * {@link ByteBufAllocator}:最终还是有8中allocator 2^3 种组合
 * {@link AbstractByteBufAllocator}
 * direct / heap
 * {@link PlatformDependent#hasUnsafe()}
 * {@link io.netty.buffer.PooledByteBufAllocator}
 * {@link PooledByteBufAllocator.PoolThreadLocalCache}
 * {@link PoolArena.HeapArena}
 * {@link PoolArena.DirectArena}
 * {@link io.netty.buffer.UnpooledByteBufAllocator}
 * <p>
 * <p>
 * <p>
 * {@link ReferenceCounted}
 * JVM 的引用计数 GC 会受循环引用困扰，而且无法管理堆外内存
 * Netty 的 refCnt 是 手动引用计数，完全由程序控制，避免了循环引用问题，并能管理池化/堆外内存，性能可控
 * {@link AbstractReferenceCounted} {@link AbstractReferenceCounted#deallocate()}
 * {@link ReferenceCountUtil}
 * <p>
 * <p>
 * memory size
 * subPage Page Chunk
 * 0-8k    8K    16M
 * <p>
 * tiny    small       normal    huge
 * 0-512B  512B-8KB    8KB-16M   16M-~
 */
public class Util {
    public static void main(String[] args) {
        ByteBufAllocator pooled = PooledByteBufAllocator.DEFAULT;
        ByteBufAllocator unpooled = UnpooledByteBufAllocator.DEFAULT;

        System.out.println("PlatformDependent.hasUnsafe = " + PlatformDependent.hasUnsafe());

        // 1. Pooled Heap
        ByteBuf pooledHeap = pooled.heapBuffer(16);
        System.out.println("Pooled Heap: " + pooledHeap.getClass().getName());

        // 2. Pooled Direct
        ByteBuf pooledDirect = pooled.directBuffer(16);
        System.out.println("Pooled Direct: " + pooledDirect.getClass().getName());

        // 3. Unpooled Heap
        ByteBuf unpooledHeap = unpooled.heapBuffer(16);
        System.out.println("Unpooled Heap: " + unpooledHeap.getClass().getName());

        // 4. Unpooled Direct
        ByteBuf unpooledDirect = unpooled.directBuffer(16);
        System.out.println("Unpooled Direct: " + unpooledDirect.getClass().getName());

        // 额外演示：使用 Unpooled 工具类
        ByteBuf ub1 = Unpooled.buffer(16);
        ByteBuf ub2 = Unpooled.directBuffer(16);
        ByteBuf ub3 = Unpooled.wrappedBuffer(new byte[16]);

        System.out.println("Unpooled.buffer(): " + ub1.getClass().getName());
        System.out.println("Unpooled.directBuffer(): " + ub2.getClass().getName());
        System.out.println("Unpooled.wrappedBuffer(): " + ub3.getClass().getName());

        // 释放
        pooledHeap.release();
        pooledDirect.release();
        unpooledHeap.release();
        unpooledDirect.release();
        ub1.release();
        ub2.release();
        ub3.release();


        // 如果你自定义类重写 equals，一定要同时重写 hashCode，否则哈希集合可能出现逻辑错误
        // 约定：equals true ⇒ hashCode 相等 哈希数据结构在桶间定位 + 桶内判断 能正确配合，使 equals 判断真正生效
        String s1 = new String("hello world");
        String s2 = "hello world";
        System.out.println(s1 == s2);   // 常量池的地址 vs 堆地址
        System.out.println(s1.equals(s2));

        String s3 = "ab";
        String s4 = "a" + "b";
        System.out.println(s3 == s4);
        System.out.println(s3.equals(s4));
        System.err.println("hello world");

    }
}
